<?php
declare (strict_types = 1);

namespace app\middleware;

use app\common\lib\Aes;

class Auth
{
    /**
     * 处理请求
     *
     * @param \think\Request $request
     * @param \Closure       $next
     * @return Response
     */
    public function handle($request, \Closure $next)
    {
        header('Access-Control-Allow-Origin:*');
        header('Content-Type:application/json; charset=utf-8');
        $is_callback = $request->param('callback', '');
        if ($is_callback) {
            $param = $request->param();
            foreach ($param as $key => $value) {
                if (empty($value)) {
                    unset($param[$key]);
                }
            }
            unset($param['_']);
        } else {
            if (!$request->isPost()) {
                echo ejson(443, '非法请求', [], $is_callback);exit;
            }
            $param = $request->post();
        }
        // var_dump($param);exit;
        $debug = env('app.is_debug') ?? 0;
        if (!$debug) {
            $flag = $this->checkSign($param);
            if ($flag !== true) {
                echo ejson(444, '签名错误', [], $is_callback);exit;
            }
        }
        $nologin = config('app.NOLOGIN');
        $class   = strtolower($request->controller());
        $action  = strtolower($request->action());
        unset($param['sign']);
        if (!empty($nologin[$class]) && ($nologin[$class] === '*' || in_array($action, $nologin[$class]))) {
            return $next($request);
        }
        $token = $request->header('token');
        if (empty($token)) {
            echo ejson(441, '请先登录', [], $is_callback);exit;
        }
        $token = $this->dataDecrypt($token);
        if (!$token) {
            echo ejson(443, '非法操作', [], $is_callback);exit;
        }
        $token_time = config('app.TOKEN_TIME');
        if (empty($token_time)) {
            $token_time = 86400;
        }
        if (time() - $token['login_time'] > $token_time) {
            echo ejson(442, '登录超时', [], $is_callback);exit;
        }
        $request->user_id = $token['id']; // 当前登录用户ID
        return $next($request);
    }

    /**
     * 验证签名
     * @author 贺强
     * @time   2019-05-28 15:14:53
     * @param  array  $data 参与验证的数据
     * @return bool         返回验证结果
     */
    private function checkSign($data = [])
    {
        // var_dump($data);exit;
        $sign = $data['sign'] ?? '';
        unset($data['sign'], $data['callback']);
        // 根据传递的参数生成新的校验码
        ksort($data);
        $str = http_build_query($data);
        $str .= ('|' . config('app.SECRET'));
        // echo $str;exit;
        $str = md5($str);
        // echo $str;exit;
        if ($sign === $str) {
            return true;
        }
        return false;
    }

    /**
     * 数据AES解密
     * @author 贺强
     * @time   2021-03-23 15:58:50
     * @param  string $ciphertext 要解密的串
     * @return array              返回解决后的数据
     */
    private function dataDecrypt($ciphertext)
    {
        $data = '';
        if (!empty($ciphertext)) {
            $data = (new Aes())->decrypt($ciphertext);
            if (!$data) {
                return false;
            }
            $param = json_decode($data, true);
            if (json_last_error() == JSON_ERROR_NONE) {
                $data = $param;
            }
        }
        return $data;
    }
}
